package com.eflow.autoconfig;

import com.eflow.engine.handler.ProcessListenerHandler;
import com.eflow.engine.handler.ProxyUserHandler;
import com.eflow.engine.listener.EflowTaskListener;
import com.eflow.engine.listener.GlobalTaskListener;
import com.eflow.engine.listener.IUserTaskCreateListener;
import com.eflow.engine.listener.TaskCreateInterceptor;
import com.eflow.engine.service.*;
import com.eflow.engine.service.impl.*;
import com.eflow.model.flowable.converter.*;
import com.eflow.model.groovy.GroovyScriptEngine;
import com.eflow.model.service.IEflowUserService;
import com.eflow.model.utils.SpringUtils;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
import org.flowable.common.engine.api.delegate.event.FlowableEventDispatcher;
import org.flowable.common.engine.api.identity.AuthenticationContext;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Iterator;

/**
 * @author hui se
 * @description
 * @create 2021-04-29 16:20
 **/
@Configuration("EflowConfig")
@EnableConfigurationProperties(EflowProperties.class)
@MapperScan("com.eflow.**.mapper")
public class EflowConfig  {

    @Configuration(proxyBeanMethods = false)
    @ConditionalOnClass(AuthenticationContext.class)
    public static class SpringSecurityAuthenticationContextConfiguration {

        public SpringSecurityAuthenticationContextConfiguration(ObjectProvider<BaseUserListConverter> userListConverters) {
            Iterator<BaseUserListConverter> iterator = userListConverters.iterator();
            while(iterator.hasNext()) {
                BaseUserListConverter next = iterator.next();
                UserTaskConverter.addConverter(next);
            }
        }
    }

    @Bean
    @ConditionalOnMissingBean(IEflowUserService.class)
    public IEflowUserService flowableUserDetailsService() {
        return new EflowUserServcieImpl();
    }


    @Bean
    public IEflowableBpmnModelService eflowableBpmnModelService() {
        return new EflowableBpmnModelServiceImpl();
    }


    @Bean
    public ProcessListenerHandler processListenerHandler() {
        return new ProcessListenerHandler();
    }

    @Bean
    public IEflowBytearrayService eflowBytearrayService() {
        return new EflowBytearrayServiceImpl();
    }


    @Bean
    public IEflowModelService eflowModelService() {
        return new EflowModelServiceImpl();
    }

    @Bean
    public UserTaskConverter userTaskConverter() {
        return new UserTaskConverter();
    }
    @Bean
    public SpringUtils springUtils() {
        return new SpringUtils();
    }

    @Bean
    public IEflowRepositoryServiceService eflowRepositoryServiceService() {
        return new EflowRepositoryServiceImpl();
    }

    @Bean
    public IEflowTaskService eflowTaskService() {
        return new EflowTaskServiceImpl();
    }

    @Bean
    public IProcessService processService() {
        return new ProcessServiceImpl();
    }

    @Bean
    public ITaskService taskService() {
        return new TaskServiceImpl();
    }

    @Bean
    public UserTaskService userTaskService() {
        return new UserTaskService();
    }

    @Bean
    public EflowTaskListener eflowTaskListener() {
        return new EflowTaskListener();
    }

    @Bean
    public TaskCreateInterceptor taskCreateInterceptor(ObjectProvider<IUserTaskCreateListener>  userTaskCreateListeners,ProcessEngineConfigurationImpl processEngineConfiguration) {
        TaskCreateInterceptor taskCreateInterceptor = new TaskCreateInterceptor(userTaskCreateListeners);
        processEngineConfiguration.setCreateUserTaskInterceptor(taskCreateInterceptor);
        return taskCreateInterceptor;

    }


    @Bean
    public GlobalTaskListener globalTaskListener( ProcessEngineConfigurationImpl processEngineConfiguration) {
        GlobalTaskListener globalTaskListener = new GlobalTaskListener();
        FlowableEventDispatcher dispatcher = processEngineConfiguration.getEventDispatcher();
        //任务创建全局监听
        dispatcher.addEventListener(globalTaskListener, FlowableEngineEventType.TASK_CREATED);
        dispatcher.addEventListener(globalTaskListener, FlowableEngineEventType.TASK_ASSIGNED);
        dispatcher.addEventListener(globalTaskListener, FlowableEngineEventType.TASK_COMPLETED);

        dispatcher.addEventListener(globalTaskListener, FlowableEngineEventType.PROCESS_STARTED);
        dispatcher.addEventListener(globalTaskListener, FlowableEngineEventType.PROCESS_COMPLETED_WITH_TERMINATE_END_EVENT);
        dispatcher.addEventListener(globalTaskListener, FlowableEngineEventType.PROCESS_COMPLETED);
        dispatcher.addEventListener(globalTaskListener, FlowableEngineEventType.ENTITY_DELETED);
        dispatcher.addEventListener(globalTaskListener, FlowableEngineEventType.CUSTOM);
        dispatcher.addEventListener(globalTaskListener, FlowableEngineEventType.PROCESS_CANCELLED);

        return globalTaskListener;
    }
    @Bean
    public FlowableConfig flowableConfig() {
        return new FlowableConfig();
    }


    @Bean
    public GroovyScriptEngine groovyScriptEngine(){
        return new GroovyScriptEngine();
    }

    @Bean
    public UserListConverter userListConverter(){
        return new UserListConverter();
    }

    @Bean
    public UserRelativeConverter userRelativeConverter (){
        return new UserRelativeConverter ();
    }
    @Bean
    public UserScriptConverter  userScriptConverter (){
        return new UserScriptConverter  ();
    }
    @Bean
    public UserStartUserConverter userStartUserConverter (){
        return new UserStartUserConverter   ();
    }
    @Bean
    public UserDeptConverter  userDeptConverter (){
        return new UserDeptConverter ();
    }

   @Bean
    public ProxyUserHandler  proxyUserHandler (){
        return new ProxyUserHandler();
    }






}
